﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.Data.SqlClient;
using System.Configuration;

namespace Ent.AccesoDatos
{
    public class DriveDataBase
    {
        TypeDataBase DataBase;
        string CadenaConexionDB;

        /// <summary>
        /// Construtor del controlador universal de acceso a datos
        /// </summary>
        /// <param name="DB">Base de datos a utilizar</param>
        /// <param name="conexion">Cadena de conexion hacia la base de datos</param>
        public DriveDataBase(TypeDataBase DB)
        {
            DataBase = DB;
            switch (DB) 
            {
                case TypeDataBase.Oracle:
                    CadenaConexionDB = ConfigurationManager.AppSettings.Get("ENTConOracle").ToString();
                    break;
                case TypeDataBase.Mysql:
                    CadenaConexionDB = ConfigurationManager.AppSettings.Get("ENTConMYSQL").ToString();
                    
                    break;
                case TypeDataBase.Sql:
                    CadenaConexionDB = ConfigurationManager.AppSettings.Get("ENTConSql").ToString();
                    break;
                default:
                    break;
            }
           
        }

        /// <summary>
        /// Permite ejecutar una consulta DataReader
        /// </summary>
        /// <param name="storeProcedure">Nombre del procedimiento almacenado</param>
        /// <param name="parametros">Listado de parametros</param>
        /// <returns>Devuelve un conjunto de datos resultado de una cosulta</returns>
        public Reader EjecutarReader(string storeProcedure, List<Parametro> parametros=null)
        {
            Reader r=null;
            IDataReader datos;
            switch (DataBase)
            {
                case TypeDataBase.Mysql:
                    var mysqlHelper = MySqlHelper.ObtenerConexion("");
                    datos = mysqlHelper.ExecuteReader(storeProcedure, parametros);
                    r = new Reader(datos);
                    break;
                case TypeDataBase.Sql:
                    datos = SqlHelper.ExecuteReader(CadenaConexionDB, storeProcedure, ParseParametros(parametros));
                    r = new Reader(datos);
                    break;             
            }

            return r;
        }

        /// <summary>
        /// Permite ejecutar una consulta 
        /// </summary>
        /// <param name="storeProcedure">Nombre del procedimiento almacenado</param>
        /// <param name="parametros">Listado de parametros</param>
        public void EjecutarQuery(string storeProcedure, List<Parametro> parametros = null)
        {
            switch (DataBase)
            {
                case TypeDataBase.Mysql:
                    var mysqlHelper = MySqlHelper.ObtenerConexion("");
                    mysqlHelper.ExecuteNonQuery(storeProcedure, parametros);
                    
                    break;
                case TypeDataBase.Sql:
                    SqlHelper.ExecuteNonQuery(CadenaConexionDB, storeProcedure, ParseParametros(parametros));
                    
                    break;
            }

         
        }

        /// <summary>
        /// Permite ejecutar una consulta Scalar
        /// </summary>
        /// <param name="storeProcedure">Nombre del procedimiento almacenado</param>
        /// <param name="parametros">Listado de parametros</param>
        /// <returns>Devuelve un dato resultado de una cosulta</returns>
        public object EjecutarScalar(string storeProcedure, List<Parametro> parametros = null)
        {
            object resultado = null;
            switch (DataBase)
            {
                case TypeDataBase.Mysql:
                    var mysqlHelper = MySqlHelper.ObtenerConexion("");
                    resultado = mysqlHelper.ExecuteScalar(CadenaConexionDB, storeProcedure, parametros);

                    break;
                case TypeDataBase.Sql:
                    resultado=SqlHelper.ExecuteScalar(CadenaConexionDB, storeProcedure, ParseParametros(parametros));

                    break;
            }

            return resultado;
        }

        /// <summary>
        /// Permite transformar los parametros que llegan en lista a un arreglo de objetos
        /// </summary>
        /// <param name="parametros">Listado de parametros</param>
        /// <returns></returns>
        object[] ParseParametros(List<Parametro> parametros)
        {
            var ne = parametros.Count;
            var i = 0;
            if (ne > 0)
            {
                object[] listaParametros=new object[ne];
                foreach (var par in parametros)
                {
                    listaParametros[i] = par.Valor;
                    i++;
                }
                return listaParametros;
            }
            else
                return null;
        }

        public void CerrarConexion()
        {
            switch (DataBase)
            {
                case TypeDataBase.Oracle:
                    break;
                case TypeDataBase.Mysql:
                    var mysqlHelper = MySqlHelper.ObtenerConexion("");
                    mysqlHelper.CerrarSessionDB();
                    break;
                case TypeDataBase.Sql:
                    break;
            }
        }
    }

    /// <summary>
    /// Clase que permite llevar la informacion de las consultas hacia un nivel superior
    /// </summary>
    public class Reader {

        private IDataReader datos;

        public IDataReader Datos
        {
            get { return datos; }
            set { datos = value; }
        }

        
        public Reader(IDataReader d)
        {
            datos = d;
        }
    }

    /// <summary>
    /// Clase que permite tener la informacion de un parametro como son: Nombre y Valor del parametro
    /// </summary>
    public class Parametro
    {
        public string Nombre { get; set; }
        public object Valor { get; set; }

        /// <summary>
        /// Contructor de los parametros
        /// </summary>
        /// <param name="nombre">Nombre del parametro</param>
        /// <param name="valor">Valor  del parametro</param>
        public Parametro(string nombre,object valor)
        {
            Nombre = nombre;
            Valor = valor;
        }
    }

    /// <summary>
    /// Enumeraciones para el tipo de base de datos
    /// </summary>
    public enum TypeDataBase
    { 
        Oracle,
        Mysql,
        Sql
    }
}
